﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Globalization;
using System.IO;
using Aron.Weiler;

namespace Medianamik.Core.Urls
{
    public class UrlDictionaryEntry : MedianamikUrl, IUrlDictionaryEntry
    {
        public UrlDictionaryEntry(Guid nodeId, Guid typeId, Guid? parentId, string hierarchicalPath,
            long position, int hierarchicalDepth, bool linkOnFirstChild, WebSite website, CultureInfo culture,
            int? pRevision, int pGeneration, string scheme, string pDomain,
            string pDomainGroup, string domainCulture, string path, string pTemplate, 
            bool excludedFromIndexation) : base(website, culture, path, excludedFromIndexation)
        {
            if (!String.IsNullOrEmpty(domainCulture) && domainCulture != culture.Name)
                throw new Exception("Domain culture should be the same page culture.");

            website.DefaultCulture = culture;
            _scheme = scheme.ToLower();

            if (!_scheme.Equals("https://") && !_scheme.Equals("http://"))
                throw new ArgumentException("Unrecognized scheme: " + _scheme, "scheme");

            _nodeId = nodeId;
            _typeId = typeId;
            _parentId = parentId;
            _hierarchicalPath = hierarchicalPath;
            _position = position;
            _hierarchicalDepth = hierarchicalDepth;
            _linkOnFirstChild = linkOnFirstChild;
            _revision = pRevision;
            _generation = pGeneration;
            _domainCulture = (domainCulture ?? "");
            _domain = pDomain.ToLower();
            _rewritedPath = pTemplate.ToLower();
            _domainGroup = (pDomainGroup ?? string.Empty).ToLower();
            _requestedPath = (website.Prefix + Path).ToLower();
            _requestedUrl = GetAbsoluteUri(Scheme, Domain, _requestedPath);
            //_rewritedUrl = GetAbsoluteUri(Scheme, Domain, RewritedPath);
            _literalRequestedUrl = _requestedUrl.ToString().ToLower();

            _nodeCulture =  culture;
        }

        private readonly string _literalRequestedUrl;

        public bool LinkOnFirstChild
        {
            get { return _linkOnFirstChild; }
        }

        public int HierarchicalDepth
        {
            get { return _hierarchicalDepth; }
        }

        public long Position
        {
            get { return _position; }
        }

        public string HierarchicalPath
        {
            get { return _hierarchicalPath; }
        }

        public Guid? ParentId
        {
            get { return _parentId; }
        }

        public Guid TypeId
        {
            get { return _typeId; }
        }

        public string LiteralRequestedUrl
        {
            get { return _literalRequestedUrl; }
        }

        private readonly CultureInfo _nodeCulture;
        public CultureInfo NodeCulture
        {
            get { return _nodeCulture; }
        }

        private readonly string _requestedPath;
        public string RequestedPath
        {
            get { return _requestedPath; }
        }

        private readonly Guid _nodeId;
        private readonly Guid _typeId;
        private readonly Guid? _parentId;
        private readonly string _hierarchicalPath;
        private readonly long _position;
        private readonly int _hierarchicalDepth;
        private readonly bool _linkOnFirstChild;

        public Guid NodeId
        {
            get { return _nodeId; }
        }

        private Uri GetAbsoluteUri(string scheme, string domain, string path)
        {
            return new Uri(scheme + domain + path, UriKind.Absolute);
        }

        private readonly int? _revision;
        public int? Revision
        {
            get { return _revision; }
        }

        private readonly int _generation;
        public int Generation
        {
            get { return _generation; }
        }

        private readonly string _scheme;
        public string Scheme
        {
            get { return _scheme; }
        }

        private readonly string _domain;
        public string Domain
        {
            get { return _domain; }
        }

        private readonly string _domainCulture;
        public string DomainCulture
        {
            get { return _domainCulture; }
        }

        private readonly string _domainGroup;
        public string DomainGroup
        {
            get { return _domainGroup; }
        }

        public bool Equals(IUrlDictionaryEntry other)
        {
            if (ReferenceEquals(null, other)) return false;
            if (ReferenceEquals(this, other)) return true;
            return Equals(other.RequestedUrl, _requestedUrl);
        }

        public override bool Equals(object obj)
        {
            if (ReferenceEquals(null, obj)) return false;
            if (ReferenceEquals(this, obj)) return true;
            if (obj.GetType() != typeof(UrlDictionaryEntry)) return false;
            return Equals((IUrlDictionaryEntry)obj);
        }

        public override int GetHashCode()
        {
            return _requestedUrl.GetHashCode();
        }

        public static bool operator ==(UrlDictionaryEntry left, UrlDictionaryEntry right)
        {
            return Equals(left, right);
        }

        public static bool operator !=(UrlDictionaryEntry left, UrlDictionaryEntry right)
        {
            return !Equals(left, right);
        }

        private readonly string _rewritedPath;
        public string RewritedPath
        {
            get { return _rewritedPath; }
        }

        private readonly Uri _requestedUrl;
        public Uri RequestedUrl
        {
            get { return _requestedUrl; }
        }

        //private readonly Uri _rewritedUrl;
        //public Uri RewritedUrl
        //{
        //    get { return _rewritedUrl; }
        //}
    }
}
